DynamoDBでGSIおよびLSIを持つテーブルの作成およびクエリをコンソールから行ってみた
こんにちは、CX事業本部の若槻です。
DynamoDBでは、セカンダリインデックスという仕様を使用して、プライマリキーとは別に追加でパーティションキーやソートキーをテーブルに持たせることにより、一つのテーブルで複数のユースケースによるクエリに対応させることができたり、検索効率を上げたりすることができたりします。
今回は、DynamoDBでGSI(グローバルセカンダリインデックス)およびLSI(ローカルセカンダリインデックス)を持つテーブルの作成およびクエリの実施を、AWSのマネジメントコンソールから行ってみました。
ユースケース
ユーザーオブジェクトとグループオブジェクトの管理を、次で紹介されているようなベストプラクティスに基づき単一のDynamoDBテーブルで行うとします。
一般的なルールとして、DynamoDB アプリケーションはできるだけ少ないテーブルを維持する必要があります。
そして今回は次のデータ取得のアクセスパターンを実現できるテーブルを考えてみます。
- 特定のIDのオブジェクトを取得
- 特定のタイプのオブジェクトをすべて取得
その場合は次のようなキーおよび属性による構成のテーブルが考えられます。
- プライマリパーティションキー(PK):
objectType
- プライマリソートキー(SK):
createdAt
- GSIのパーティションキー(GSI-PK):
objectId
- LSIのソートキー(LSI):
updatedAt
- 非キー属性(Attr):
objectName
、member
、belongingTo
objectType (PK) |
createdAt (SK) |
updatedAt (LSI) |
objectId (GSI-PK) |
objectName (Attr) |
member (Attr) |
belongingTo (Attr) |
|
---|---|---|---|---|---|---|---|
グループオブジェクト | Group | {Timestamp} | {Timestamp} | {GroupId} | {GroupName} | ({UserId1}, {UserId2}, {GroupId1}…) | |
ユーザーオブジェクト | User | {Timestamp} | {Timestamp} | {UserId} | {UserName} | ({Group1}, {Group2},…) |
この構成のDynamoDBテーブルをマネジメントコンソールから作成してみます。
テーブルの作成
AWSのマネジメントコンソールでDynamoDBテーブルの新規作成ページを開きます。
[テーブル名]と[プライマリキー]を指定したら、[テーブル設定]で[デフォルト設定の使用]のチェックを外します。
[セカンダリインデックス]で[インデックスの追加]をクリックします。まずGSIから追加していきます。
[インデックスの追加]ダイアログが開きます。[パーティションキー]でGSIのパーティションキーとしてobjectId
を指定します。[インデックス名]はインデックス種類とキーが分かる名前としました。[射影される属性]は、GSI使用時はすべての属性の値を取得したいのですべて
を指定します。最後に[インデックスの追加]をクリックします。
GSIを追加できました。再度[インデックスの追加]をクリックします。次はLSIを追加していきます。
[インデックスの追加]ダイアログが開きます。LSIのプライマリキーとして[パーティションキー]でobjectType
を指定し、[ソートキー]でupdatedAt
を追加します。GSIと同様に[インデックス名]はインデックス種類とキーが分かる名前、[射影される属性]はすべて
を指定します。LSIとする場合は[ローカルセカンダリインデックスとしての作成]にチェックを入れます。(このチェックボックスは[パーティションキー]でプライマリパーティションキーを指定し、[ソートキーの追加]をチェックした時のみチェック可能となりました。)最後に[インデックスの追加]をクリックします。
LSIも追加できました。
最後に[作成]をクリックしてテーブルの作成を完了させます。
テーブルを作成できました。
クエリの実施
作成したテーブルに対して各種方法でクエリを実施してみます。
オブジェクトのアイテムは次のようにテーブルに追加しました。
プライマリキーによるクエリ
プライマリキーであるパーティションキーobjectType
とソートキーcreatedAt
によるクエリをしてみます。前述したアクセスパターンのうちだと「2. 特定のタイプのオブジェクトをすべて取得」に該当します。
オペレーション種類でクエリ
、対象で[テーブル]〜
を選択し、objectType
とcreatedAt
を指定すると検索ができました。また、検索結果の並び順はソートキーであるcreatedAt
で昇順にソートされています。
GSIによるクエリ
GSIによるクエリをしてみます。アクセスパターンのうちだと「1. 特定のIDのオブジェクトを取得」に該当します。
オペレーション種類でクエリ
、対象で[索引]GSI〜
を選択し、objectId
を指定すると検索ができました。
LSIによるクエリ
LSIによるクエリをしてみます。アクセスパターンのうちだと「2. 特定のタイプのオブジェクトをすべて取得」に該当します。
オペレーション種類でクエリ
、対象で[索引]LSI〜
を選択し、objectType
とupdatedAt
を指定すると検索ができました。また、検索結果の並び順はソートキーであるupdatedAt
で昇順にソートされており、ここがプライマリキーによるクエリとの違いとなります。
おわりに
DynamoDBでGSIおよびLSIを持つテーブルの作成およびクエリをコンソールから行ってみたのでご紹介をしました。
RDBとは異なりNoSQLであるDynamoDBはなるべく少ないテーブルでシステムを構築するのがベストプラクティスであるため、今回のように異なる種類のデータを同じテーブル上で管理する構成はよくあるケースだと思います。そういう場合にセカンダリインデックスがとても役に立つということを今回知ることができました。
以上